package com.yx.changdao.web.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yx.changdao.common.annotation.AutoLog;
import com.yx.changdao.common.annotation.ShiroDesc;
import com.yx.changdao.common.data.Pager;
import com.yx.changdao.common.data.Result;
import com.yx.changdao.common.entity.*;
import com.yx.changdao.common.enums.Category;
import com.yx.changdao.common.exception.AlertException;
import com.yx.changdao.common.utils.*;
import com.yx.changdao.common.vo.count.newleader.ExecuteCount;
import com.yx.changdao.common.vo.count.newleader.TotalCount;
import com.yx.changdao.service.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 问题 公共模块
 *
 * @Auther: wangzd
 * @create 2020/04/03 16:51
 */
@RestController
@RequestMapping("/problem")
public class ProblemController {

    /**
     * 问题服务
     */
    @Autowired
    private ProblemService problemService;
    /**
     * 问题处理结果
     */
    @Autowired
    private ProblemDealService problemDealService;

    /**
     * 问题信息(在分配之前)服务
     */
    @Autowired
    private ProblemInfoService problemInfoService;
    @Autowired
    private SysDictService sysDictService;

    @Autowired
    private GridInfoService gridInfoService;
    /**
     * 通用
     * 总控申请审批 疑难件 获取已经分配的部门
     * 总控分配- 获取已经分配的部门
     */
    @AutoLog
    @GetMapping("/already/deps")
    public Result deps(@RequestParam("proInfoId") Integer proInfoId) {

        List<Department> depts = problemService.list(new QueryWrapper<Problem>()
                .select(Problem.ID,Problem.DEP_ID,Problem.DEP_NAME)
                .eq(Problem.PROBLEM_INFO_ID, proInfoId)).stream().map(x -> {

            Department department = new Department();
            department.setDepId(x.getDepId());
            department.setDepName(x.getDepName());
            return department;
        }).collect(Collectors.toList());
        return Result.ok().data(depts);
    }


    /**
     * 执行-问题录入-查看
     * 总控-问题分配-查看
     * <p>
     * 查看 problemInfo（主信息）
     * <p>
     * 获得主键id 获取问题信息。
     *
     * @param
     * @return Result
     */
    @AutoLog
    @GetMapping("/info/{proInfoId}")
    /*@RequiresPermissions("problem:info:look")
    @ShiroDesc("问题信息:查看")*/
    public Result get(@PathVariable("proInfoId") Integer proInfoId) throws AlertException {
        ProblemInfo problemInfo = problemInfoService.getById(proInfoId);
        if (problemInfo == null) {
            throw new AlertException("未找到相关问题信息");
        }
        GridInfo gridInfo = gridInfoService.getById(problemInfo.getGridId());
        if (null != gridInfo) {
            problemInfo.setGridId(Integer.valueOf(gridInfo.getGridNum()));
        }
        problemInfo.setResidentIdcard(DesensitizationUtils.idEncrypt(problemInfo.getResidentIdcard()));
        return Result.ok().data(problemInfo);
    }

    /**
     * 问题录入修改查看
     * @param proInfoId
     * @return
     * @throws AlertException
     */
    @AutoLog
    @GetMapping("/modify/info/{proInfoId}")
    /*@RequiresPermissions("problem:info:look")
    @ShiroDesc("问题信息:查看")*/
    public Result getModifyInfo(@PathVariable("proInfoId") Integer proInfoId) throws AlertException {
        ProblemInfo problemInfo = problemInfoService.getById(proInfoId);

        if (problemInfo == null) {
            throw new AlertException("未找到相关问题信息");
        }
        return Result.ok().data(problemInfo);
    }



    /**
     * 难度上报列表
     */
    @AutoLog
    @GetMapping("/dep/problem")
    public Result getDepProblem(
            @RequestParam(value = "page") Long page,
            @RequestParam(value = "limit", required = false) Integer limit)  {
        if (limit == null) {
            limit = SysConst.LIMIT_PAGE;
        }
        // 分页配置
        Page<Problem> pager = new Page<>(page, limit);
        // 根据请求解析条件。
        QueryWrapper<Problem> qw = SysUtils.autoCnd(Problem.class);
        qw.eq(Problem.DEP_ID, SysUtils.currentUser().getDepId());
        qw.ne(Problem.CATEGORY,Category.SEF.n());

        qw.orderByDesc(Problem.CREATE_TIME); //时间倒序
        // 获取分页结果集。
        Page<Problem> problemPage = this.problemService.page(pager, qw);
        problemPage.getRecords().forEach(p -> p.setResidentIdcard(DesensitizationUtils.idEncrypt(p.getResidentIdcard())));
        Map<String, Object> map = new HashMap<>();
        map.put("list", problemPage.getRecords());
        map.put("pager", new Pager(problemPage));
        return Result.ok().data(map);
    }

    /**
     * 问题难度上报申请
     *
     * @param
     * @return Result
     */

    @AutoLog
    @PutMapping("/diff/report")
    @RequiresPermissions("problem:process:level")
    @ShiroDesc("问题办理:难度上报")
    @Transactional(rollbackFor = {Exception.class})
    public Result diffReport(@RequestParam("id") Integer id,
                             @RequestParam("difficultLevel") String difficultLevel) throws AlertException {

        if(StringUtils.isEmpty(difficultLevel)){
           throw new AlertException("办理难度为空") ;
        }

        List<String> lev = sysDictService.getByParent(33);
        Faster.throwNotIn(difficultLevel, lev,"办里难度值不合法");
        Problem problem = problemService.getById(id);
        if (Faster.isNull(problem)) {
            throw new AlertException("未查到问题信息");
        }
        if (Category.SEF.n().equals(problem.getCategory())) {
            throw new AlertException("自主解决问题类不可申请问题难度");
        }
        if (1 == problem.getDifficultLevelStatus() || 2 == problem.getDifficultLevelStatus() ) {
            throw new AlertException("已提交审批或审批通过无法重复提交");
        }
        problem.setDifficultLevel(difficultLevel);
        problem.setDifficultLevelStatus(1);
        problem.setDifficultLevelSubmitTime(Faster.now());
        boolean b = problemService.updateById(problem);
        if (!b) {
            throw new AlertException("问题难度上报失败");
        }
        UpdateWrapper<ProblemInfo> updateWrapper = new UpdateWrapper<ProblemInfo>().set(ProblemInfo.IF_DIFFICULT_LEVEL_REPORT, 1)
                .eq(ProblemInfo.PROBLEM_INFO_ID, problem.getProblemInfoId());
        problemInfoService.update(updateWrapper);
        return Result.ok("问题难度上报成功");
    }


    /**
     * 执行-难度上报-查看
     *
     * @param
     * @return Result
     */

    @AutoLog
    @GetMapping("/{proId}")
    /*@RequiresPermissions("problem:look")
    @ShiroDesc("问题:查看")*/
    public Result getProblem(@PathVariable("proId") Integer proId) throws AlertException {
        Problem problem = problemService.getById(proId);
        if (problem == null) {
            throw new AlertException("未找到相关问题信息");
        }
        problem.setResidentIdcard(DesensitizationUtils.idEncrypt(problem.getResidentIdcard()));
        return Result.ok().data(problem);
    }

    /**
     * 返回问题处理结果list
     *
     * @param problemId
     */
    @AutoLog
    @GetMapping("/deals")
    /*@RequiresPermissions("problem:look")
    @ShiroDesc("问题:查看")*/
    public Result getDeals( @RequestParam("problemId") Integer problemId,
                            @RequestParam(value = "page") Long page,
                            @RequestParam(value = "limit", required = false) Integer limit) {

        if (limit == null) {
            limit = SysConst.LIMIT_PAGE;
        }
        // 分页配置
        Page<ProblemDeal> pager = new Page<>(page, limit);
        // 根据请求解析条件。
        QueryWrapper<ProblemDeal> qw = SysUtils.autoCnd(ProblemDeal.class);
        qw.orderByDesc(ProblemDeal.CREATE_TIME); //时间倒序

        qw.eq(ProblemDeal.PROBLEM_ID, problemId);
        // 获取分页结果集。
        Page<ProblemDeal> dealPage = this.problemDealService.page(pager, qw);

        Map<String, Object> map = new HashMap<>();
        map.put("list", dealPage.getRecords());
        map.put("pager", new Pager(dealPage));
        return Result.ok().data(map);
    }

    /**
     * ----问题录入统计--------------------------------------------------------------------------------------------------
     */

    /**
     * 数据统计 录入上方统计
     * WEEK,
     * MONTH,
     * THREE_MONTH,
     * ALL;
     */
    @AutoLog
    @GetMapping("/count/input/{type}")
    @RequiresPermissions("problem:count:input")
    @ShiroDesc("统计:录入统计")
    public Result countInput(@PathVariable("type") String type) throws AlertException {

        Calendar cld = Calendar.getInstance(Locale.CHINA); // 时间基准,默认当前时间
        return Result.ok().data(problemService.countInput(type, cld));
    }

    /**
     * 数据统计 录入趋势图
     */
    @AutoLog
    @GetMapping("/count/input/trend/{type}")
    @RequiresPermissions("problem:count:input")
    @ShiroDesc("统计:录入统计")
    public Result trendInput(@PathVariable("type") String type) throws AlertException {

        Calendar cld = Calendar.getInstance(Locale.CHINA); // 时间基准,默认当前时间
        return Result.ok().data(problemService.trend(type, cld, 1));
    }

    /**
     * 数据统计 录入饼图
     */
    @AutoLog
    @GetMapping("/count/input/pie/{type}")
    @RequiresPermissions("problem:count:input")
    @ShiroDesc("统计:录入统计")
    public Result pieInput(@PathVariable("type") String type) throws AlertException {

        Calendar cld = Calendar.getInstance(Locale.CHINA); // 时间基准,默认当前时间
        return Result.ok().data(problemService.pieCount(type, cld));
    }

    /**
     * ---总控部门领导数据查看-------------------------------------------------------------------------------------------
     */

    /**
     * 总控 领导 首页
     */
    @AutoLog
    @GetMapping("/count/leader/home")
    @RequiresPermissions("problem:home:leader")
    @ShiroDesc("统计:总控领导统计")
    public Result countLeaderHome()  {

        TotalCount totalCount = problemService.totalCount();
        return Result.ok().data(totalCount);
    }

    /**
     * 总控 领导 上方
     * 数据统计
     * WEEK
     * MONTH,
     * THREE_MONTH,
     * ALL;
     */
    @AutoLog
    @GetMapping("/count/leader/{type}")
    @RequiresPermissions("problem:count:leader")
    @ShiroDesc("统计:总控领导统计")
    public Result countLeader(@PathVariable("type") String type) throws AlertException {

        Calendar cld = Calendar.getInstance(Locale.CHINA); // 时间基准,默认当前时间
        return Result.ok().data(problemService.countLeader(type, cld));
    }

    /**
     * 总控 领导 趋势图
     * 数据统计
     * WEEK
     * MONTH,
     * THREE_MONTH,
     * ALL;
     */
    @AutoLog
    @GetMapping("/count/leader/trend/{type}")
    @RequiresPermissions("problem:count:leader")
    @ShiroDesc("统计:总控领导统计")
    public Result trendLeader(@PathVariable("type") String type) throws AlertException {

        Calendar cld = Calendar.getInstance(Locale.CHINA); // 时间基准,默认当前时间
        return Result.ok().data(problemService.trend(type, cld, 2));
    }

    /**
     * 总控 领导 左下
     * sort 1 按上报数量排名
     * sort 2 按处理数排名
     * sort 3 按满意度排名
     * sort 4 按办结率排名
     *
     * type: WEEK
     * type: MONTH,
     * type: THREE_MONTH,
     * type: ALL;
     */
    @AutoLog
    @GetMapping("/count/leader/sort")
    @RequiresPermissions("problem:count:leader")
    @ShiroDesc("统计:总控领导统计")
    public Result countDept(@RequestParam("sort") Integer sort,
                            @RequestParam("type") String type) throws AlertException {

        Calendar cld = Calendar.getInstance(Locale.CHINA); // 时间基准,默认当前时间
        return Result.ok().data(problemService.sortCountDept(sort, type, cld));
    }

    /**
     * 总控 领导 右下
     * type : WEEK
     * type: MONTH,
     * type:   THREE_MONTH,
     * type:  ALL;
     */
    @AutoLog
    @GetMapping("/count/leader/oth")
    @RequiresPermissions("problem:count:leader")
    @ShiroDesc("统计:总控领导统计")
    public Result countDeptBack(@RequestParam("type") String type) throws AlertException {

        Calendar cld = Calendar.getInstance(Locale.CHINA); // 时间基准,默认当前时间
        return Result.ok().data(problemService.othCountDept(type, cld));
    }

    /**
     * -----执行部门领导数据查看--------------------------------------------------------------------------------------------
     */

    /**
     * 执行 首页
     */
    @AutoLog
    @GetMapping("/count/execute/home")
    @RequiresPermissions("problem:home:execute")
    @ShiroDesc("统计:总控领导统计")
    public Result countExecuteHome() {

        ExecuteCount executeCount = problemService.executeCount();
        return Result.ok().data(executeCount);
    }

    /**
     * 执行 领导 上方
     * 数据统计
     * WEEK
     * MONTH,
     * THREE_MONTH,
     * ALL;
     */
    @AutoLog
    @GetMapping("/count/execute/{type}")
    @RequiresPermissions("problem:count:execute")
    @ShiroDesc("统计:执行领导统计")
    public Result countExecute(@PathVariable("type") String type) throws AlertException {

        Calendar cld = Calendar.getInstance(Locale.CHINA); // 时间基准,默认当前时间
        return Result.ok().data(problemService.countExecute(type, cld));
    }

    /**
     * 执行 领导 趋势图
     * 数据统计
     * WEEK
     * MONTH,
     * THREE_MONTH,
     * ALL;
     */
    @AutoLog
    @GetMapping("/count/execute/trend/{type}")
    @RequiresPermissions("problem:count:execute")
    @ShiroDesc("统计:执行领导统计")
    public Result trendExecute(@PathVariable("type") String type) throws AlertException {

        Calendar cld = Calendar.getInstance(Locale.CHINA); // 时间基准,默认当前时间
        return Result.ok().data(problemService.trend(type, cld, 3));
    }

    /**
     * 执行 领导 左下
     * sort 2 按处理数排名
     * sort 3 按满意度排名
     * <p>
     *    type :WEEK
     * type: MONTH,
     * type:    THREE_MONTH,
     * type:   ALL;
     */
    @AutoLog
    @GetMapping("/count/execute/sort")
    @RequiresPermissions("problem:count:execute")
    @ShiroDesc("统计:执行领导统计")
    public Result countEmp(@RequestParam("sort") Integer sort,
                           @RequestParam("type") String type) throws AlertException {

        Calendar cld = Calendar.getInstance(Locale.CHINA); // 时间基准,默认当前时间
        return Result.ok().data(problemService.sortCountEmp(sort, type, cld));
    }

    /**
     * 执行 领导 右下
     * type :WEEK
     * type: MONTH,
     * type:   THREE_MONTH,
     * type:  ALL;
     */
    @AutoLog
    @GetMapping("/count/execute/oth")
    @RequiresPermissions("problem:count:execute")
    @ShiroDesc("统计:执行领导统计")
    public Result countEmp(@RequestParam("type") String type) throws AlertException {

        Calendar cld = Calendar.getInstance(Locale.CHINA); // 时间基准,默认当前时间
        return Result.ok().data(problemService.othCountEmp(type, cld));
    }


    /**
     * 疑难件导出
     * @throws Exception
     */
    @AutoLog
    @GetMapping("/difficult/export")
    public void difficultExport() throws Exception {

        List<ProblemInfo> list = problemInfoService.list(new QueryWrapper<ProblemInfo>().eq(ProblemInfo.IF_DIFFICULT,1));
        for (ProblemInfo problemInfo : list) {
            GridInfo gridInfo = gridInfoService.getById(problemInfo.getGridId());
            if (null != gridInfo) {
                problemInfo.setGridId(Integer.valueOf(gridInfo.getGridNum()));
            }
        }
        List<String> cloudms = new ArrayList<>();
        cloudms.add("residentName:反馈居民姓名");
        cloudms.add("residentAddress:反馈居民地址");
        cloudms.add("residentIdcard:反馈居民身份证号");
        cloudms.add("residentPhone:反馈居民手机号");
        cloudms.add("category:意见建议类别");
        cloudms.add("industryCategory:意见建议行业类别");

        cloudms.add("contact1Name:联户人1姓名");
        cloudms.add("contact1Phone:联户人1手机号");
        cloudms.add("contact2Name:联户人2姓名");
        cloudms.add("contact2Phone: 联户人2手机号");

        cloudms.add("content:意见建议内容");
        cloudms.add("difficultLevel:办理难度");

        cloudms.add("gridId:网格编号");
        cloudms.add("buildCode:楼编号");
        cloudms.add("buildName:楼名称");
        cloudms.add("unit:单元号");
        cloudms.add("doorPlate:室号");

        ExcelImportExportUtils.writeExcelByCloum(list, SysUtils.getResponse(), "导出", cloudms);
    }

    /**
     * 更新交办意见
     * @param problemInfoId
     * @param assignOpinion
     * @return
     */
    @AutoLog
    @PutMapping("/modify/assignOpinion")
    public Result modifyAssignOpinion(@RequestParam("problemInfoId") String problemInfoId,
                                      @RequestParam("assignOpinion") String assignOpinion) throws AlertException {
        if(StringUtils.isBlank(assignOpinion)){
            throw new AlertException("拟办意见不能为空");
        }
        UpdateWrapper<ProblemInfo> updateWrapper = new UpdateWrapper<ProblemInfo>()
                .set(ProblemInfo.ASSIGN_OPINION, assignOpinion)
                .eq(ProblemInfo.PROBLEM_INFO_ID, problemInfoId);
        boolean b = problemInfoService.update(updateWrapper);
        if (!b) {
            throw new AlertException("保存拟办意见失败");
        }
        return Result.ok("保存拟办意见成功");
    }

    /**
     * 更新交办意见
     * @param problemInfoId
     * @return
     */
    @AutoLog
    @GetMapping("/assignOpinion")
    public Result getAssignOpinion(@RequestParam("problemInfoId") String problemInfoId) throws AlertException {
        ProblemInfo info = problemInfoService.getById(problemInfoId);
        if(Objects.isNull(info)){
            throw new AlertException("未查到问题信息");
        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("assignOpinion",info.getAssignOpinion());
        map.put("enable",false);

        if(StringUtils.isNotBlank(info.getAssignOpinion())){
            map.put("enable",true);
        }

        return Result.ok().data(map);
    }
}
